package com.zboin.ucenter.auth;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zboin.ucenter.mapper.UserInfoMapper;
import com.zboin.ucenter.model.UserInfo;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.Collections;

/**
 * @author zhboom
 * @date 2025/7/30 22:06
 */
@Component
public class UsernamePasswordAuthenticationProvider implements AuthenticationProvider {

    private final UserInfoMapper userInfoMapper;
    private final PasswordEncoder passwordEncoder;

    public UsernamePasswordAuthenticationProvider(UserInfoMapper userInfoMapper) {
        this.userInfoMapper = userInfoMapper;
        this.passwordEncoder = new BCryptPasswordEncoder();
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = authentication.getCredentials().toString();

        UserInfo userInfo = userInfoMapper.selectOne(
                new QueryWrapper<UserInfo>().eq("username", username));

        if (userInfo == null) {
            throw new BadCredentialsException("Invalid username or password");
        }

        // 验证密码
        if (!passwordEncoder.matches(password, userInfo.getPassword())) {
            throw new BadCredentialsException("Invalid username or password");
        }

        return new UsernamePasswordAuthenticationToken(userInfo, password, Collections.emptyList());
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
